package com.woniuxy.project115.kaer.user.controller;


import cn.hutool.core.bean.BeanUtil;
import com.woniuxy.project115.kaer.commons.util.JwtUtil;
import com.woniuxy.project115.kaer.commons.util.Result;
import com.woniuxy.project115.kaer.user.dto.LoginDto;
import com.woniuxy.project115.kaer.user.form.AccountRegisterForm;
import com.woniuxy.project115.kaer.user.form.CodeRegisterForm;
import com.woniuxy.project115.kaer.user.form.RealNameAuthForm;
import com.woniuxy.project115.kaer.user.form.ScoreChangeForm;
import com.woniuxy.project115.kaer.user.param.AccountRegisterParam;
import com.woniuxy.project115.kaer.user.param.CodeRegisterParam;
import com.woniuxy.project115.kaer.user.param.ScoreChangeParam;
import com.woniuxy.project115.kaer.user.service.UserInfoService;
import com.woniuxy.project115.kaer.user.util.RedisKey;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author fyy
 * @since 2025年02月17日
 */
@RestController
@RequestMapping("/userInfo")
@Api(tags = "用户类型接口")
public class UserInfoController {

    @Resource
    private UserInfoService userInfoService;
    @Resource
    private StringRedisTemplate stringRedisTemplate;
    /**
 * 账号密码注册
 *
 * 本方法用于处理用户账号密码注册请求通过传入账号和密码参数完成注册流程
 *
 * @return 返回注册结果包括成功或失败的信息
 */
@PostMapping("/accountRegister")
@ApiOperation("账号密码注册")
public Result accountRegister(@RequestBody AccountRegisterForm arf) throws Exception {
    userInfoService.accountRegister(BeanUtil.toBean(arf, AccountRegisterParam.class));
    return Result.succeed("注册成功",null);
}

//验证码发送注册验证码接口
    @PostMapping("/sendRegisterCode")
    @ApiOperation("发送注册验证码")
    public Result sendRegisterCode(String phone) throws Exception {
        userInfoService.sendRegisterCode(phone);
        return Result.succeed("注册验证码发送成功",null);
    }

    //验证码注册接口
    @PostMapping("/codeRegister")
    @ApiOperation("验证码注册")
    public Result codeRegister(@RequestBody CodeRegisterForm crf) throws Exception {
        userInfoService.codeRegister(BeanUtil.toBean(crf, CodeRegisterParam.class));
        return Result.succeed("注册成功",null);
    }

    //发送登录验证码接口
    @PostMapping("/sendLoginCode")
    @ApiOperation("发送登录验证码")
    public Result sendLoginCode(String phone) throws Exception {
        userInfoService.sendLoginCode(phone);
        return Result.succeed("登录验证码发送成功",null);
    }

    //短信登录接口
    @PostMapping("/smsLogin")
    @ApiOperation("短信登录")
    public Result smsLogin(String phone, String code, HttpServletResponse response) throws Exception {
        final LoginDto loginDto = userInfoService.smsLogin(phone, code);
        //生成jwt token并返回
        final Map<String, Object> stringObjectMap = BeanUtil.beanToMap(loginDto);
        //生成短期token
        final String accessToken = JwtUtil.createToken(stringObjectMap,30);
        //生成长期token
        final String refreshToken = JwtUtil.createToken(stringObjectMap, 3 * 24 * 60);
        //将短期token存入redis
        stringRedisTemplate.opsForValue().set(RedisKey.ACCESS_EXPIRE(accessToken),"",30,TimeUnit.MINUTES);
        //将长期token存入redis
        stringRedisTemplate.opsForValue().set(RedisKey.ACCESS_REFRESH(accessToken),refreshToken,3*24*60,TimeUnit.HOURS);
        //通过响应头响应给前端
        //通过响应头将jwt响应给客户端
        response.setHeader("token",accessToken);
        //在跨域请求访问时 必须要公开请求头 前端才能获取列
        response.setHeader("Access-Control-Expose-Headers","token");
        return Result.succeed("登录成功",loginDto);
    }

    //账号密码登录接口
    @PostMapping("/accountLogin")
    @ApiOperation("账号密码登录")
    public Result accountLogin(String account, String password, HttpServletResponse response,HttpServletRequest req) throws Exception {
        final LoginDto loginDto = userInfoService.accountLogin(account, password,req);
        //生成jwt token并返回
        final Map<String, Object> stringObjectMap = BeanUtil.beanToMap(loginDto);
        //生成短期token
        final String accessToken = JwtUtil.createToken(stringObjectMap,2*24*60);
        //生成长期token
        final String refreshToken = JwtUtil.createToken(stringObjectMap, 3 * 24 * 60);
        //通过响应头响应给前端
        //通过响应头将jwt响应给客户端
        response.setHeader("token",accessToken);
        //将短期token存入redis
        stringRedisTemplate.opsForValue().set(RedisKey.ACCESS_EXPIRE(accessToken),"",30,TimeUnit.MINUTES);
        //将长期token存入redis
        stringRedisTemplate.opsForValue().set(RedisKey.ACCESS_REFRESH(accessToken),refreshToken,3*24*60,TimeUnit.HOURS);
        //在跨域请求访问时 必须要公开请求头 前端才能获取列
        response.setHeader("Access-Control-Expose-Headers","token");
        return Result.succeed("登录成功",loginDto);
    }

    //积分变动接口
    @PostMapping("/scoreChange")
    @ApiOperation("消费积分接口")
    public Result scoreChange(@RequestBody ScoreChangeForm scoreChangeForm) throws Exception {
        userInfoService.scoreChange(BeanUtil.toBean(scoreChangeForm, ScoreChangeParam.class));
        return Result.succeed("积分变动成功",null);
    }


    //userInfoId 获取用户信息接口
    @GetMapping("/getUserInfoScore")
    @ApiOperation("获取用户积分接口")
    public Result<Integer> getUserInfoScore(Integer userId) throws Exception {
        return Result.succeed("获取用户积分",userInfoService.getById(userId).getScore());
    }


    //用户实名认证接口
    @PostMapping("/realNameAuth")
    @ApiOperation("用户实名认证接口")
    public Result realNameAuth(@RequestBody RealNameAuthForm raf) throws Exception {
        userInfoService.realNameAuth(raf);
        return Result.succeed("实名认证成功",null);
    }

    //查询所有用户信息接口
    @GetMapping("/getAllUserInfo")
    @ApiOperation("查询所有用户信息接口")
    public Result getAllUserInfo() throws Exception {
        return Result.succeed("查询所有用户信息",userInfoService.getAllUserInfo());
    }

    //更新用户状态接口
    @PutMapping("/updateUserState")
    @ApiOperation("用户状态更新成功")
    public Result banUser(Integer userId,Integer state) throws Exception {
        userInfoService.banUser(userId,state);
        return Result.succeed("更新用户状态成功",null);
    }

    //根据id获取用户信息接口
    @GetMapping("/getUserById")
    @ApiOperation("根据id获取用户信息接口")
    public Result getUserInfoById(Integer userId) throws Exception {
        return Result.succeed("获取用户信息成功",userInfoService.getUserById(userId));
    }

}

